home *** CD-ROM | disk | FTP | other *** search
/ Windows News 2010 Summer - Disc 1 / WN_Ete2010_CD1.iso / Onglet5 / Weezo / Weezo setup.exe / {code_appDir} / www / js / musicDB-src.js < prev    next >
Text File  |  2010-05-19  |  16KB  |  441 lines

  1. var mDBGroupBy, mDBDisplayType, mDBMixedFilter; // Currently applied group / filter
  2. var mDBDestId; // Currently unfolded/to be unfolded details id
  3. var mDBDestIdUnfolded; // Set to mDBDestId when unfolding has actually started
  4. var mDBData; // Current selection data array
  5. var mDBNbItems // Nb of items in current selection;
  6. /**
  7.  * Init
  8.  * @Param: pl: playlist content array
  9.  */
  10. function init(pl){
  11.     plRefresh(pl);
  12.     dgi('searchInput').focus();
  13.     fas('','refreshDisplay');
  14. }
  15.  
  16. /**
  17.  * Layout functions
  18.  */
  19. /*
  20. Inlined function
  21. function resizeDivs(){
  22.     alignBottom(dgi('explorerDiv'),winMe,5);
  23.     alignBottom(dgi('selectionDiv'),dgi('explorerDiv'),0);
  24.     alignBottom(dgi('filterDiv'),dgi('explorerDiv'));
  25.     // Reset margins of covers details
  26.     if(mDBDestId && mDBDisplayType=='covers') coversDetailSetMargins(mDBDestId)
  27. }
  28. */
  29. function winResized(w,h){resizeDivs();}
  30.  
  31. /**
  32.  * Adjust covers display type details div position
  33.  */
  34. function coversDetailSetMargins(destId){
  35.     var s=dgi('det'+destId).style;
  36.     s.marginLeft=(10-1*dgi('id'+destId).offsetLeft)+'px';
  37.     s.width=(0.99*dgi("selectionDiv").offsetWidth-40)+'px'
  38.     s.marginRight=(30-dgi('id'+destId).offsetLeft-dgi("selectionDiv").offsetWidth)+'px'
  39.     s.display='';
  40. }
  41. function coversDetailSetMarginsWA(colId,step){ 
  42.     if(step=='doneUnfold' && mDBDisplayType==='covers') {
  43.         coversDetailSetMargins(colId.substr(3))
  44.         // Re-center on top of item
  45.         wl.fadeStyle('selectionDiv','scrollTop',dgi('id'+mDBDestId).offsetTop-((phpBrowser=='ie')?0:36),'exponential',3);
  46.     }
  47. }
  48.  
  49. // Invisible cover IMG onload
  50. function coverLoaded(n){
  51.     if(n.offsetWidth==1) n.src=coverDefaultSrc; // 1x1 pixel = no cover => display default cover
  52.     else if(mDBNbItems>40 || n.offsetWidth==0) n.style.visibility='' // Too many items or image width=0 (chrome WA on already cached images): display
  53.     else fade(n,0,1,3) // Else fade-in
  54. }
  55.  
  56. /**
  57.  * User request a database update
  58.  */
  59. function updateDatabase(){fas(false,'updateDatabase',false,false,'sync')}
  60.  
  61.  
  62. function formatedTime(secs){
  63.     if(!secs) return '-';
  64.     var hours=Math.floor(secs/3600),minutes=Math.floor(Math.floor((secs%3600))/60),seconds=Math.floor(secs%60);
  65.     if(hours>0 && minutes<10) minutes="0"+minutes;
  66.     if(seconds<10) seconds="0"+seconds;
  67.     if(hours>0) return hmsCaption.replace(/%1/,hours).replace(/%2/,minutes).replace(/%3/,seconds);
  68.     else return msCaption.replace(/%1/,minutes).replace(/%2/,seconds);
  69. }
  70.  
  71.  
  72. /**
  73.  * @desc: Insert img src into a template, using regular image template
  74.  * @param t:
  75.  * @param img: src of image, false to display default image
  76.  */
  77. function insertCover(t, img){
  78.     if(img.length>0){
  79.         if(sourceType=='iTunes') t=t.replace(/COVERSRC/g,coverTemplate).replace(/IMAGEPATH/,img.replace(/#/,lPID));
  80.         else t=t.replace(/COVERSRC/g,coverTemplate).replace(/IMAGEPATH/,img);
  81.     }
  82.     else t=t.replace(/COVERSRC/g,coverDefaultSrc)
  83.  
  84.     t=t.replace(/EXTRAHTML=""/i,'width="'+fCW+'" height="'+fCW+'"');
  85.     return t.replace(/imgtag/gi,'img');
  86. }
  87.  
  88. // PLAY FUNCTIONS
  89. function playTrack(trackId){view(trackId,dAWW,dAWH);}
  90. function playAlbum(artistName, albumName){view('album/'+artistName+'/'+albumName,dAWW,dAWH)}
  91. function playArtist(artistName){view('artist/'+artistName,dAWW,dAWH)}
  92. function inlineSetSongPlayed(imgSrc,artist,album,title){
  93.     dgi('inlinePlayerImg').src=imgSrc;
  94.     dgi('inlineArtist').innerHTML=artist;
  95.     dgi('inlineAlbum').innerHTML=album;
  96.     dgi('inlineTitle').innerHTML=title;
  97. }
  98. function inlineUpdatePlayerInfo(trackId){fas(trackId,'inlineUpdatePlayerInfo');}
  99.  
  100. // PLAYLIST FUNCTIONS
  101. function plAddArtist(artistName){if(mIsProcessing) return; mProcessing(true);fas(artistName,'plAddArtist');}
  102. function plAddAlbum(artistName, albumName){if(mIsProcessing) return; mProcessing(true);fas(artistName,'plAddAlbum',albumName);}
  103. function plAddPlaylist(playlistId){if(mIsProcessing) return; mProcessing(true);fas(playlistId,'plAddPlaylist');}
  104. function plAddTrack(trackId){if(mIsProcessing) return; mProcessing(true);fas(trackId,'plAddTrack');}
  105. function plAddAllShuffle(){if(mIsProcessing) return; mProcessing(true);fas(0,'plAddAllShuffle');}
  106.  
  107. // FILTER FUNCTIONS
  108. function changeDisplayType(ndt){fas(ndt,'changeDisplayType');}
  109. function changeItemsPerPage(nb){fas(nb,'changeItemsPerPage');}
  110. function changeOffset(selectSeq){fas(selectSeq,'changeOffset');}
  111. function groupBy(item){
  112.     dgi('groupBy'+item).checked="checked";
  113.     fas(item,'changeGroupBy');
  114. }
  115. function search(exp){
  116.     searchValue=exp;
  117.     dgi('groupBySearch').checked='checked';
  118.     fas(exp,'search');
  119. }
  120. function searchRealTime(exp){
  121.     if(searchValue==exp) return;
  122.     searchValue=exp;
  123.     dgi('groupBySearch').checked='checked';
  124.     fas(exp,'search',1);
  125. }
  126. function validateSearch(e){
  127.     if(e) kc=e.which; else {if(W.event) kc=W.event.keyCode; else return;}
  128.     if(kc==13 && dgi('searchInput').value!="") search(dgi("searchInput").value);
  129.     if(dgi('searchInput').value.length>2) searchRealTime(dgi('searchInput').value);
  130. }
  131.  
  132. /**
  133.  * Function called on user request to show Artist/Album/Playlist detail (or on click on already selected Artist/Album/Playlist).
  134.  *             this function is also called back by insertDetail function to display inserted content. In this case, only detailType && destId are provided
  135.  */
  136. function showDetail(detailType, artistName, albumName, destId, calledBackByInsertDetail){
  137.     var n=dgi("det"+destId), pn=dgi('id'+destId);
  138.     // If another detail is already shown, 1st collapse it
  139.     if(mDBDestId && !calledBackByInsertDetail) {
  140.         // Collapse previously shown details (anim only if not collapsing because another one is opened)
  141.         hideDetail(mDBDestId,mDBDestId!=destId);
  142.  
  143.         // If selected frame was the unfolded one, exit;
  144.         if(mDBDestId===destId) {
  145.             mDBDestId=false;
  146.             return;
  147.         }
  148.     }
  149.     
  150.     mDBDestId=destId;
  151.  
  152.     // User-click (not server callback) Scroll to top of selected Album/Artist/Playlist
  153.     if(!calledBackByInsertDetail) {
  154.         wl.fadeStyle('selectionDiv','scrollTop',dgi('id'+destId).offsetTop-((phpBrowser=='ie')?0:36),'exponential',10,'unfoldDetail()');
  155.         // If content (already) loaded, wait for fadeStyle to callback unfoldDetail
  156.         if(n.innerHTML!='') return;
  157.     }
  158.     else{
  159.         // Server called back showDetail after having filled n.innerHTML, and scroll anim complete: unfold
  160.         if(n.innerHTML!='' && mDBDestIdUnfolded==destId) unfoldDetail();
  161.     }
  162.     
  163.     // Content not loaded: request to server
  164.     if(!n.innerHTML){
  165.         D.comForm.data1.value=albumName;
  166.         fas(artistName,'showDetail', destId, detailType);
  167.         D.comForm.data1.value='*resSpecific*';
  168.     }
  169. }
  170.  
  171. function unfoldDetail(){
  172.     var destId=mDBDestId,n=dgi("det"+destId);
  173.  
  174.     mDBDestIdUnfolded=mDBDestId;
  175.  
  176.     // If content not yet loaded, wait for 2nd callback
  177.     if(!n.innerHTML) return;
  178.  
  179.  
  180.     // Adjust position of detail node
  181.     if(mDBDisplayType=='covers') coversDetailSetMargins(destId)
  182.  
  183.     // Unfold node
  184.     dgi("col"+destId).style.display='inline';
  185.  
  186.     // Cover view : adjust detail node margins so it fits overflow:scroll div's width
  187.     wl.nodeCollapseToggle("col"+destId,0,'coversDetailSetMarginsWA')
  188. }
  189.  
  190. /**
  191.  * Fold details
  192.  * Skip anim if unfolding another detail (prevents scroll positionning issues)
  193.  * If anim skipped, destroy content to prevent other issues with absolute objects popping out of folded frame
  194.  */
  195. function hideDetail(nodeId,skipAnim){
  196.     if(skipAnim) {
  197.         var s=dgi("col"+nodeId).style; s.height=((phpBrowser=='ie')?1:0)+'px';s.visibility="hidden";s.margin=0;s.padding=0;
  198.         dgi("det"+nodeId).innerHTML='';
  199.     }
  200.     else {
  201.         dgi("col"+nodeId).style.display='none';
  202.     }
  203. }
  204.  
  205.  
  206. /**
  207.  * Insert into album/artist template the compact or detailed list of tracks
  208.  * @param tracksData: array of tracks
  209.  * @param displayType: 'full' (playlist detail) or 'compact' (all other details)
  210.  */
  211. function trackDetail(tracksData, displayType){
  212.     var trackHTML,o,l=tracksData.length,trackData;
  213.     // Template for single track
  214.     var trackTemplate=dgi('trackDetail'+((displayType=='compact')?"Compact":"Full")).innerHTML;
  215.     // Template for track group header
  216.     var html=dgi('trackDetail'+((displayType=='compact')?"Compact":"Full")+'Header').innerHTML.replace(/</g,'<').replace(/>/g,'>');
  217.     // Template for track group footer
  218.     var footerTemplate=dgi('trackDetail'+((displayType=='compact')?"Compact":"Full")+'Footer').innerHTML.replace(/</g,'<').replace(/>/g,'>');
  219.     
  220.     // Create tracks HTML
  221.     for(o=0;o<l;o++){
  222.         trackData=tracksData[o];
  223.         trackHTML=trackTemplate.replace(/TRACKTIME/,formatedTime(trackData[2])).replace(/TRACKNAME/g,trackData[1]).replace(/TRACKID/g,trackData[0]);
  224.         trackHTML=trackHTML.replace(/ARTISTNAME/,trackData[3]).replace(/ALBUMNAME/g,trackData[4]).replace(/PARITY/,(o%2)?'odd':'even');
  225.         html+=trackHTML.replace(/TRACKNUMBER/,o+1)
  226.     }
  227.     return html+footerTemplate;
  228. }
  229.  
  230. /**
  231.  * Show Artist/Album/Playlist detail
  232.  * @param detailType: Artist/Album/Playlist
  233.  * @param mixedDisplayType: Artist/Album/Playlist
  234.  *
  235.  */
  236. function insertDetail(detailType, mixedDisplayType, destId, data){
  237.     var albumTemplate,i,o,album,html="", tracksHtml='', aH='', artistName;
  238.  
  239.     if(detailType=='Artist'){
  240.         artistName=dgi("name"+destId).innerHTML;
  241.         albumTemplate=dgi("albumDetail"+mixedDisplayType.substr(7)).innerHTML;
  242.  
  243.         // Insert artist name header if existing (used for covers view)
  244.          if(dgi('detHeader'+destId)) html=dgi('detHeader'+destId).innerHTML.replace(/ARTISTNAME/,artistName);
  245.  
  246.         // Foreach album
  247.         // Array(Album1 name, Album1 artwork, Album1 year, Album1 total time, Album1 nb tracks,
  248.         //                              Array(
  249.         //                                  Array(Track1 PID, Track1 name, Track1 total time),
  250.         //                                  Array(Track2 PID, Track2 name, Track2 total time),
  251.         //                                  ...
  252.         //                          ...),
  253.         for(i=0;i<data.length;i++){
  254.             album=data[i];
  255.             aH=albumTemplate.replace(/ITEMID/g,'destId'+destId+'-'+i);
  256.             aH=aH.replace(/ALBUMNAMEJS/g,album[0].replace(/'/g,"\\'"));    //"\
  257.             aH=aH.replace(/ALBUMNAME/g,album[0]);
  258.             aH=insertCover(aH,album[1]);
  259.             aH=aH.replace(/YEAR/,album[2]);
  260.             aH=aH.replace(/TOTALTIME/,formatedTime(album[3]));
  261.             aH=aH.replace(/NBTRACKS/g,album[4]);
  262.             aH=aH.replace(/ARTISTNAMEJS/g,artistName.replace(/'/g,"\\'"));    //"\
  263.             aH=aH.replace(/ARTISTNAME/g,artistName);
  264.             // Insert tracks
  265.             tracksHtml=trackDetail(album[5],'compact');
  266.             if(i==data.length-1) aH=aH.replace(/ENDSEPARATOR=""/i,'style="display:none"')
  267.             html+=aH.replace(/TRACKS/,tracksHtml);
  268.         }
  269.     }
  270.  
  271.     if(detailType=='Album'){
  272.         artistName=(dgi("artistName"+destId))?dgi("artistName"+destId).innerHTML:'';
  273.         albumName=dgi("name"+destId).innerHTML;
  274.         // Insert artist name header if existing (used for covers view)
  275.         if(dgi('detHeader'+destId)) html=dgi('detHeader'+destId).innerHTML.replace(/ALBUMNAME/,artistName);
  276.  
  277.         html+=trackDetail(data,'compact');
  278.         html=dgi('albumTrackDetailCompact').innerHTML.replace(/TRACKS/g,html);
  279.     }
  280.     if(detailType=='Playlist'){
  281.         // Insert tracks
  282.         html+=trackDetail(data,'full');
  283.         html=dgi('albumTrackDetailCompact').innerHTML.replace(/TRACKS/g,html);
  284.     }
  285.  
  286.     // Insert into detail node
  287.     dgi("det"+destId).innerHTML=html;
  288.  
  289.     // Unfold / show
  290.     showDetail(detailType,0,0,destId,1)
  291. }
  292.  
  293. function updateSelect(selectArray){
  294.     var html="";
  295.     var txt="";
  296.     for(var i=0;i<selectArray.length;i++){
  297.         html+='<option value="'+i+'"'+((selectArray[i].substr(0,1)=='S')?' selected':'')+'>'+selectArray[i].substr(1)+'</option>';
  298.     }
  299.     if(selectArray.length>0) dgi("selectionRange").innerHTML='<select size="1" class="textInput" onChange="changeOffset(this.value)">'+html+'</select>'; else dgi("selectionRange").innerHTML='';
  300. }
  301.  
  302.  
  303. /**
  304.  * MAIN ASYNC VIEW UPDATE FUNCTION
  305.  *
  306.  * @param groupBy: 'artist', 'album', 'playlist', 'track'
  307.  * @param displayType: 'compact', 'full', 'cover', 'detail'
  308.  * @param mixedFilter: groupBy+displayType
  309.  * @param dataArray: array of artists and/or albums and/or playlists and/or tracks
  310.  * @param selectArray: array needed for album/artist/playlist <select> update
  311.  * @param currentOffset: offset in albums/artists/playlists
  312.  * @param replace: true to replace view by generated one, false to add to currently displayed (used for mixed search results where displayList function is called once for every result type
  313.  */
  314. function displayList(groupBy, displayType,  mixedFilter, dataArray, selectArray, currentOffset, replace){
  315.     var html='',i;
  316.     mDBGroupBy=groupBy;
  317.     mDBDisplayType=displayType;
  318.     mDBMixedFilter=mixedFilter;
  319.     mDBDestId=false;
  320.     mDBData=dataArray;
  321.     mDBNbItems=dataArray.length;
  322.  
  323.     // Update album/artist/playlist <select>
  324.     if(replace) updateSelect(selectArray);
  325.  
  326.     // Build list HTML
  327.     switch(groupBy){
  328.         case "artist":
  329.             for(i=0;i<dataArray.length;i++) html+=groupByArtist(mixedFilter,dataArray[i],i+currentOffset);
  330.             break;
  331.         case "album":
  332.             for(i=0;i<dataArray.length;i++) html+=groupByAlbum(mixedFilter,dataArray[i],i+currentOffset);
  333.             break;
  334.         case "playlist":
  335.             for(i=0;i<dataArray.length;i++) html+=groupByPlaylist(mixedFilter,dataArray[i],i+currentOffset);
  336.             break;
  337.         case "tracks":
  338.             for(i=0;i<dataArray.length;i++) html+=groupByTrack(dataArray[i],i+currentOffset);
  339.         default:
  340.     }
  341.  
  342.     // Update view with created HTML
  343.     if(replace) dgi("selectionDiv").innerHTML=html; else dgi("selectionDiv").innerHTML+=html;
  344.  
  345.     if(replace && dataArray.length==0) displayNoResults();
  346.     //rebuildDraggableItems();
  347. }
  348.  
  349. function displayNoResults(){
  350.     dgi("selectionDiv").innerHTML=dgi("noSearchResult").innerHTML;
  351. }
  352.  
  353. /**
  354.  * Update View with a full/compact/covers view artist item
  355.  * @param: displayType: "artistFull", "artistCompact", "artistCovers"
  356.  * @item: array(artist name (0), nb of albums (1), nb of tracks (2), cover img src (3))
  357.  * @index: sequential index
  358.  */
  359. function groupByArtist(displayType, item, index){
  360.     if(displayType=='searchCompact') displayType='artistCompact';
  361.     if(displayType=='searchCovers'||displayType=='searchFull') displayType='artistFull';
  362.  
  363.     // Get template
  364.     var t=dgi("groupByA"+displayType.substr(1)).innerHTML
  365.     //if(displayType=='artistFull') addDraggableItem('_idArtist'+index);
  366.  
  367.     t=t.replace(/ITEMID/g,"Artist"+index);
  368.     t=insertCover(t,item[3]);
  369.     t=t.replace(/ARTISTNAMEJS/g,item[0].replace(/'/g,"\\'"));    //foo.replace(/'/g,"\\'"));
  370.     t=t.replace(/ARTISTNAME/g,item[0]);
  371.     t=t.replace(/NBTRACKS/,item[2]);
  372.     t=t.replace(/PARITY/,(index%2)?' odd':' even');
  373.     // If more than one track, show unfold button
  374.     if(displayType=='artistCompact' && item[2]>1) t=t.replace(/hidden/,'')
  375.     return t.replace(/NBALBUMS/,item[1]);
  376. }
  377.  
  378.  
  379. /**
  380.  * Update View with a full/compact/covers view Album item
  381.  * @param: displayType: "albumFull", "albumCompact", "albumCovers"
  382.  * @item: array(album name (0), artist name (1), nb of tracks (2), total time (3), cover img src (4))
  383.  * @index: sequential index
  384.  */
  385. function groupByAlbum(displayType, item, index){
  386.     if(displayType=='searchCompact') displayType='albumCompact';
  387.     if(displayType=='searchCovers'||displayType=='searchFull') displayType='albumFull';
  388.  
  389.     // Get template
  390.     var t=dgi("groupByA"+displayType.substr(1)).innerHTML
  391.     t=t.replace(/ITEMID/g,"Album"+index);
  392.     t=insertCover(t,item[4]);
  393.     t=t.replace(/ARTISTNAMEJS/g,item[1].replace(/'/g,"\\'"));    //foo.replace(/'/g,"\\'"));
  394.     t=t.replace(/ALBUMNAMEJS/g,item[0].replace(/'/g,"\\'"));    //foo.replace(/'/g,"\\'"));
  395.     t=t.replace(/ARTISTNAME/g,item[1]);
  396.     t=t.replace(/ALBUMNAME/g,item[0]);
  397.     t=t.replace(/TOTALTIME/,formatedTime(item[3]));
  398.     t=t.replace(/PARITY/,(index%2)?' odd':' even');
  399.     
  400.     // If more than one track, show unfold button
  401.     if(displayType=='albumCompact' && item[2]>1) t=t.replace(/hidden/,'')
  402.     return t.replace(/NBTRACKS/,item[2]);
  403. }
  404.  
  405.  
  406.  
  407. /**
  408.  * Update View with a independant track item (search result ?)
  409.  * @item: array(track id (0), track name (1), album name (2), artist name (3), total time (4))
  410.  * @index: sequential index
  411.  */
  412. function groupByTrack(item, index){
  413.     t=dgi("trackGroup").innerHTML;
  414.     t=t.replace(/ITEMID/g,"Tracks"+index);
  415.     t=t.replace(/TRACKID/g,item[0]);
  416.     t=t.replace(/ARTISTNAMEJS/g,item[3].replace(/'/g,"\\'"));
  417.     t=t.replace(/ALBUMNAMEJS/g,item[2].replace(/'/g,"\\'"));
  418.     t=t.replace(/ARTISTNAME/g,item[3]);
  419.     t=t.replace(/ALBUMNAME/g,item[2]);
  420.     t=t.replace(/TRACKNAME/g,item[1]);
  421.     t=t.replace(/PARITY/,(index%2)?' odd':' even');
  422.     return t.replace(/TRACKTIME/,formatedTime(item[4]));
  423. }
  424.  
  425.  
  426. /**
  427.  * Update View with a full/compact/covers view Playlist item
  428.  * @param: displayType: "playlistFull", "playlistCompact", "playlistCovers"
  429.  * @item: array(playlist id (0), playlist name (1), nb of tracks (2))
  430.  * @index: sequential index
  431.  */
  432. function groupByPlaylist(displayType, item, index){
  433.     var t=dgi("groupByPlaylistCompact").innerHTML;
  434.     t=t.replace(/ITEMID/g,"Playlist"+index);
  435.     t=t.replace(/PLAYLISTID/g,item[0]);
  436.     t=t.replace(/PLAYLISTNAME/g,item[1]);
  437.     t=t.replace(/PARITY/,(index%2)?' odd':' even');
  438.     return t.replace(/NBTRACKS/,item[2]);
  439. }
  440.  
  441. D.onkeyup=validateSearch;